package com.xbongbong.paas.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.help.FieldAttrHelper;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateNodeEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.RelatedPersonnelEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkDetailPojo;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.menu.InitMenuHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.ContractCompareModel;
import com.xbongbong.paas.model.ContractCompareUserModel;
import com.xbongbong.paas.model.ContractEditFileModel;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.model.PaasProcessTemplateNodeModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.ItemDataPoJo;
import com.xbongbong.paas.pojo.dto.UserListDTO;
import com.xbongbong.paas.pojo.vo.ContractCompareDetailVO;
import com.xbongbong.paas.pojo.vo.ContractCompareListVO;
import com.xbongbong.paas.pojo.vo.ContractCompareVO;
import com.xbongbong.paas.pojo.vo.SearchDataInConditionVO;
import com.xbongbong.paas.pojo.vo.UserListVO;
import com.xbongbong.paas.service.ContractCompareService;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.URLEncodeUtils;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleSaveDTO;
import com.xbongbong.pro.cabinetfile.pojo.CabinetFilePojo;
import com.xbongbong.pro.cabinetfile.pojo.vo.CabinetFileListGetVO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.contractCompare.pojo.ComparePoJo;
import com.xbongbong.pro.contractCompare.pojo.ContractCompareFeeInfoPojo;
import com.xbongbong.pro.contractCompare.pojo.ContractCompareUrlPojo;
import com.xbongbong.pro.contractCompare.pojo.dto.CheckCanLocalUploadDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareConditionDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareConsumptionDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareFileSelectDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareGetMoreSumDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareHistoryCompareDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareListDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareOrderDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareRefusedFileSelectDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareUpdateStaffDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareUrlDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractCompareUserDTO;
import com.xbongbong.pro.contractCompare.pojo.dto.ContractDataListDTO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractCompareConsumptionVO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractCompareMsgVO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractCompareOrderVO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractCompareUserListVO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractCompareUserVO;
import com.xbongbong.pro.contractCompare.pojo.vo.ContractDataListVO;
import com.xbongbong.pro.domain.entity.AppModuleEntity;
import com.xbongbong.pro.domain.entity.ContractCompareUserEntity;
import com.xbongbong.pro.enums.ContractCompareFeeStatusEnum;
import com.xbongbong.pro.enums.ContractCompareUrlOpenEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.TimeTypeEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ContractCompareErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.CRMMenuEnum;
import com.xbongbong.pro.enums.menu.enums.JXCMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.onlineEditor.TemplateFieldValuePojo;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.OnlineEditorConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CabinetFileEntity;
import com.xbongbong.saas.domain.entity.ContractCompareEntity;
import com.xbongbong.saas.domain.entity.ContractEditFileEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.PurchaseUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.enums.BusinessFieldEnum;
import com.xbongbong.saas.enums.ContractCompareStatusEnum;
import com.xbongbong.saas.enums.ContractCompareThirdPartyErrorEnum;
import com.xbongbong.saas.enums.ListOptionEnum;
import com.xbongbong.saas.enums.ListOptionTabEnum;
import com.xbongbong.saas.enums.ListSearchEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractCompareEnum;
import com.xbongbong.saas.enums.business.ContractCompareFormTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.model.AppModuleModel;
import com.xbongbong.saas.model.CabinetFileModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractSubDataModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.PurchaseSubDataModel;
import com.xbongbong.saas.model.PurchaseUserModel;
import com.xbongbong.saas.service.AppModuleService;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.FeeLogEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.FeeLogModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.ContractCompareUtil;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTransferDataEntity;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import com.xbongbong.workflow.model.WorkflowTaskNodeModel;
import com.xbongbong.workflow.model.WorkflowTransferDataModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import static com.xbongbong.paas.constant.MessageConstant.NO_PERMISSION_MSG;
import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author zhushuainan
 * @title: ContractCompareServiceImpl
 * @projectName xbb-pro
 * @description: 合同比对
 * @date 2022/11/17 15:27
 */
@Service("ContractCompareServiceImpl")
public class ContractCompareServiceImpl implements ContractCompareService {
    private static final Logger LOG = LoggerFactory.getLogger(ContractCompareServiceImpl.class);

    /**
     * 图片类型常量，可以手动添加
     */
    private static String[] supportedFileType = {"doc","docx","pdf","wps","xls","xlsx","txt","jpg", "jpeg", "png", "tif", "tiff"};

    @Resource
    private InitMenuHelp initMenuHelp;
    @Resource
    private AppModuleModel appModuleModel;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private ContractCompareUtil contractCompareUtil;
    @Resource
    private UserModel userModel;
    @Resource
    private UserService userService;
    @Resource
    private ContractCompareUserModel contractCompareUserModel;
    @Resource
    private ContractCompareModel contractCompareModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private FeeLogModel feeLogModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private AppModuleService appModuleService;
    @Resource
    private WorkflowTransferDataModel workflowTransferDataModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private PaasProcessTemplateNodeModel paasProcessTemplateNodeModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private PurchaseUserModel purchaseUserModel;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private ContractSubDataModel contractSubDataModel;
    @Resource
    private PurchaseSubDataModel purchaseSubDataModel;
    @Resource
    private CabinetFileModel cabinetFileModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private WorkflowTaskNodeModel workflowTaskNodeModel;
    @Resource
    private  ContractEditFileModel contractEditFileModel;

    @Override
    public BaseVO initContractCompare(MenuInitDTO menuInitDTO) throws XbbException {
        AppModuleEntity appModule = appModuleModel.getByAlias(SystemAppMenuEnum.CONTRACT_COMPARE.getAlias());
        if (Objects.isNull(appModule)){
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620001);
        }
        menuInitDTO.setName(appModule.getName());
        menuInitDTO.setIcon(appModule.getIcon());
        initMenuHelp.menuInit(menuInitDTO);
        return new BaseVO();
    }

    @Override
    public ContractCompareVO list(ContractCompareListDTO contractCompareListDTO) throws XbbException {
        //1 判断查看权限
        if (!contractCompareListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CONTRACT_COMPARE_RESULT_VIEW.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017, String.format(I18nMessageUtil.getMessage(NO_PERMISSION_MSG), ProPermissionAliasEnum.CONTRACT_COMPARE_RESULT_VIEW.getMemo()));
        }
//        //2 判断数据权限
        saasListDataPermissionHelp.listDataPermission(contractCompareListDTO.getConditions(), contractCompareListDTO.getLoginUser(), contractCompareListDTO.getBusinessType(), null);
        // 3 表头
        List<FieldAttrEntity> headList = new ArrayList<>();
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        fieldAttrEntity.setAttr(ListOptionEnum.OPTION.getAttr());
        fieldAttrEntity.setAttrName(ListOptionEnum.OPTION.getAttrName());
        fieldAttrEntity.setFieldType(FieldTypeEnum.OPTION.getType());
        headList.add(fieldAttrEntity);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(8);
        FieldAttrHelper.createList(ContractCompareEnum.class, new ArrayList<>(), null, headList, explainMap);
        headList.forEach(item->{
            if (Objects.equals(item.getAttr(), ContractCompareEnum.COMPARE_CONTRACT_NAME.getSaasAttr()) || Objects.equals(item.getAttr(), ContractCompareEnum.STANDARD_CONTRACT_NAME.getSaasAttr())) {
                LinkDetailPojo linkDetail = new LinkDetailPojo();
                linkDetail.setAttr(item.getAttr());
                linkDetail.setSaasMark(SaasMarkEnum.SAAS.getCode());
                item.setLinkDetail(linkDetail);
            }
        });
        //4 数据查询
        ContractCompareVO contractCompareVO = new ContractCompareVO();
        contractCompareVO.setHeadList(headList);
        List<ContractCompareDetailVO> dataESList = contractCompareUtil.getDataList(contractCompareListDTO, contractCompareVO);
        Set<String> userSet = dataESList.stream().map(ContractCompareDetailVO::getCreatorId).collect(Collectors.toSet());
        List<UserEntity> userList = userModel.getByUserIdIn(contractCompareListDTO.getCorpid(), userSet);
        Map<String, String> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
        JSONObject option_0 = new JSONObject();
        JSONObject option = new JSONObject();
        option.put("attr", "option_contract_compare");
        option.put("value", ListOptionTabEnum.VIEW.getAttrName());
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(option);
        option_0.put("value", jsonArray);
        PaasMenuEntity contractMenu = paasMenuModel.getByAlias(CRMMenuEnum.CONTRACT.getAlias(), contractCompareListDTO.getCorpid());
        PaasMenuEntity purchaseMenu = paasMenuModel.getByAlias(JXCMenuEnum.PURCHASE.getAlias(), contractCompareListDTO.getCorpid());
        List<ContractCompareListVO> dataList = new ArrayList<>();
        dataESList.forEach(item->{
            ContractCompareListVO contractCompareListVO = new ContractCompareListVO();
            BeanUtil.copyProperties(item, contractCompareListVO);
//          前端需要一个值为id的dataId,所以加上这个属性
            contractCompareListVO.setDataId(item.getId());
            if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode())) {
                contractCompareListVO.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                contractCompareListVO.setSubBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                contractCompareListVO.setMenuId(contractMenu.getId());
                contractCompareListVO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            } else if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode())) {
                contractCompareListVO.setBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                contractCompareListVO.setSubBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                contractCompareListVO.setMenuId(purchaseMenu.getId());
                contractCompareListVO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            }
            contractCompareListVO.setCreatorId(userMap.get(item.getCreatorId()));
            contractCompareListVO.setOption_0(option_0);
            if (Objects.equals(item.getCompareStatus(), ContractCompareStatusEnum.SUCCESS.getCode())) {
                contractCompareListVO.setCompareStatus(ContractCompareStatusEnum.SUCCESS.getMemo());
            } else {
                //渲染比对失败原因
                contractCompareListVO.setResultUrl(null);
                contractCompareListVO.setFailureReason(item.getResultUrl());
                contractCompareListVO.setCompareStatus(ContractCompareStatusEnum.FAILURE.getMemo());
            }
            if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode())) {
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.CONTRACT_ORDER.getMemo());
            } else if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode())){
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getMemo());
            } else {
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.LOCAL_UPLOAD.getMemo());
            }
            ContractCompareUrlPojo contractCompareUrlPojo = new ContractCompareUrlPojo();
            contractCompareUrlPojo.setContractCompareId(item.getId());
            String resultCrmUrl = contractCompareUtil.packagingCompareResultUrlToCrmUrl(contractCompareUrlPojo);
            contractCompareListVO.setResultUrl(resultCrmUrl);

            dataList.add(contractCompareListVO);
        });
        contractCompareVO.setPaasFormDataESList(dataList);
        contractCompareVO.setTotal(contractCompareVO.getPageHelper().getRowsCount());


        //3 新建按钮
        List<ButtonPojo> topButtonList = new ArrayList<>();
        contractCompareVO.setTopPermissions(getTopPermission(contractCompareListDTO, topButtonList));

        return contractCompareVO;
    }

    @Override
    public SearchDataInConditionVO conditionList(ContractCompareConditionDTO contractCompareConditionDTO) throws XbbException {
        //1 判断查看权限
        if (!contractCompareConditionDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CONTRACT_COMPARE_RESULT_VIEW.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017, String.format(I18nMessageUtil.getMessage(NO_PERMISSION_MSG), ProPermissionAliasEnum.CONTRACT_COMPARE_RESULT_VIEW.getMemo()));
        }

        ContractCompareListDTO contractCompareListDTO = new ContractCompareListDTO();
        BeanUtil.copyProperties(contractCompareConditionDTO, contractCompareListDTO);

       //2 判断数据权限
        saasListDataPermissionHelp.listDataPermission(new ArrayList<>(), contractCompareConditionDTO.getLoginUser(), XbbRefTypeEnum.CONTRACT_COMPARE_RESULT.getCode(), null);

        SearchDataInConditionVO searchDataInConditionVO = new SearchDataInConditionVO();
        List<ItemDataPoJo> itemDataList = new ArrayList<>();
        String attr = contractCompareConditionDTO.getAttr();
        if (Objects.equals(attr, ContractCompareEnum.CREATOR_ID.getSaasAttr())) {
            List<UserEntity> userList = null;
            if (Objects.nonNull(contractCompareConditionDTO.getValue()) && StringUtil.isNotEmpty(contractCompareConditionDTO.getValue().toString())) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", contractCompareConditionDTO.getCorpid());
                param.put("nameLike", contractCompareConditionDTO.getValue());
                param.put(ParameterConstant.LEAVE_MARKS, BasicConstant.ONE);
                //param.put("del", 0);
                userList = userModel.findEntitys(param);
            }
            if (CollectionUtils.isNotEmpty(userList)) {
                for (UserEntity userVO : userList) {
                    ItemDataPoJo itemDataPoJo = new ItemDataPoJo();
                    itemDataPoJo.setValue(userVO.getUserId());
                    itemDataPoJo.setText(userVO.getName());
                    itemDataList.add(itemDataPoJo);
                }
            }
            searchDataInConditionVO.setItems(itemDataList);
            return  searchDataInConditionVO;
        }



        contractCompareListDTO.setPage(0);
        contractCompareListDTO.setPageSize(10);
        ContractCompareVO contractCompareVO = new ContractCompareVO();
        List<ContractCompareDetailVO> dataList = contractCompareUtil.getDataList(contractCompareListDTO, contractCompareVO);
        Map<String, String> userMap = null;
        if (Objects.equals(attr, ContractCompareEnum.CREATOR_ID.getSaasAttr())) {
            List<String> userIdList = dataList.stream().map(ContractCompareDetailVO::getCreatorId).collect(Collectors.toList());
            List<UserEntity> userList = userModel.getByUserIdIn(contractCompareConditionDTO.getCorpid(), userIdList);
            userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
        }
        Set<String> hashSet = new HashSet<>(16);
        for (ContractCompareDetailVO contractCompareDetailVO : dataList) {
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(contractCompareDetailVO);
            String text;
            if (Objects.equals(attr, ContractCompareEnum.CREATOR_ID.getSaasAttr())) {
                String creatorId = contractCompareDetailVO.getCreatorId();
                if (StringUtil.isNotEmpty(creatorId) && !hashSet.contains(creatorId)) {
                    text = userMap.get(creatorId);
                    hashSet.add(text);
                } else {
                    continue;
                }
            } else {
                Object textObject = jsonObject.get(contractCompareConditionDTO.getAttr());
                if (Objects.nonNull(textObject) && !hashSet.contains(textObject.toString())) {
                    text = textObject.toString();
                    hashSet.add(text);
                } else {
                    continue;
                }
            }
            ItemDataPoJo itemDataPoJo = new ItemDataPoJo();
            itemDataPoJo.setText(text);
            itemDataPoJo.setValue(text);
            itemDataList.add(itemDataPoJo);
        }
        searchDataInConditionVO.setItems(itemDataList);
        return searchDataInConditionVO;
    }

    @Override
    public JSONObject startCompare(ContractCompareDTO contractCompareDTO) throws XbbException {
        Integer formType = contractCompareDTO.getFormType();
        Boolean inApproval = contractCompareDTO.getInApproval();
        boolean openWorkFlow = commonHelp.isOpenWorkFlow(contractCompareDTO.getCorpid());
        String result = contractCompareUtil.contractCompare(contractCompareDTO);
        JSONObject resultJson = JSONObject.parseObject(result);
        String  previewUrl = "";
        JSONObject jsonObject = new JSONObject();
        Integer compareStatus = ContractCompareStatusEnum.SUCCESS.getCode();
        if (Objects.equals(200, resultJson.getInteger("code"))) {
            previewUrl = (resultJson.getJSONObject("result")).getString("preview_url");
            jsonObject.put("resultUrl", previewUrl);
        } else {
            compareStatus = ContractCompareStatusEnum.FAILURE.getCode();
        }
        List<ContractEntityExt> contractList = null;
        List<PurchaseEntityExt> purchaseList = null;
        PaasProcessDataEntity paasProcessDataEntity = null;
        List<Long> dataIdList = contractCompareDTO.getCompareList().stream().map(ComparePoJo::getDataId).collect(Collectors.toList());
        if (Objects.equals(formType, ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode())) {
            if (inApproval && !openWorkFlow) {
                paasProcessDataEntity = paasProcessDataModel.getByTaskId(contractCompareDTO.getProcessTaskId(), contractCompareDTO.getCorpid());
            } else {
                contractList = contractModel.findEntitysByIdIn(contractCompareDTO.getCorpid(), DelEnum.NORMAL.getDel(), dataIdList);
            }
        } else if (Objects.equals(formType, ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode())) {
            if (inApproval && !openWorkFlow) {
                paasProcessDataEntity = paasProcessDataModel.getByTaskId(contractCompareDTO.getProcessTaskId(), contractCompareDTO.getCorpid());
            } else {
                purchaseList = purchaseModel.getPurchaseListByIdIn(contractCompareDTO.getCorpid(), dataIdList);
            }
        }
        //插入数据库和ES
        ContractCompareEntity contractCompareEntity = new ContractCompareEntity();
        if (Objects.equals(compareStatus, ContractCompareStatusEnum.SUCCESS.getCode())) {
            contractCompareEntity.setResultUrl(previewUrl);
        } else {
            ContractCompareThirdPartyErrorEnum thirdPartyErrorEnum = ContractCompareThirdPartyErrorEnum.getByCode(resultJson.getInteger("code"));
            if (Objects.nonNull(thirdPartyErrorEnum)) {
                contractCompareEntity.setResultUrl(thirdPartyErrorEnum.getMemo());
            } else {
                contractCompareEntity.setResultUrl(resultJson.getString("message"));
            }
        }
        contractCompareEntity.setCorpid(contractCompareDTO.getCorpid());
        if (Objects.equals(formType, ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode()) && Objects.nonNull(paasProcessDataEntity)) {
            contractCompareEntity.setStandardContractName(JSONObject.parseObject(paasProcessDataEntity.getData()).getString(ContractEnum.NAME.getAttr()));
            contractCompareEntity.setCompareContractName(JSONObject.parseObject(paasProcessDataEntity.getData()).getString(ContractEnum.NAME.getAttr()));
        } else if (Objects.equals(formType, ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode()) && Objects.nonNull(paasProcessDataEntity)) {
            contractCompareEntity.setStandardContractName(JSONObject.parseObject(paasProcessDataEntity.getData()).getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
            contractCompareEntity.setCompareContractName(JSONObject.parseObject(paasProcessDataEntity.getData()).getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
        } else if (Objects.equals(formType, ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode()) && CollectionsUtil.isNotEmpty(contractList)) {
            contractCompareEntity.setStandardContractName(contractList.get(0).getData().getString(ContractEnum.NAME.getAttr()));
            if (contractList.size() > 1) {
                contractCompareEntity.setCompareContractName(contractList.get(1).getData().getString(ContractEnum.NAME.getAttr()));
            } else {
                contractCompareEntity.setCompareContractName(contractList.get(0).getData().getString(ContractEnum.NAME.getAttr()));
            }
        } else if (Objects.equals(formType, ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode()) && CollectionsUtil.isNotEmpty(purchaseList)) {
            contractCompareEntity.setStandardContractName(purchaseList.get(0).getData().getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
            if (purchaseList.size() > 1) {
                contractCompareEntity.setCompareContractName(purchaseList.get(1).getData().getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
            } else {
                contractCompareEntity.setCompareContractName(purchaseList.get(0).getData().getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
            }
        }
        contractCompareEntity.setStandardContractFile(contractCompareDTO.getCompareList().get(0).getFileName());
        contractCompareEntity.setCompareContractFile(contractCompareDTO.getCompareList().get(1).getFileName());
        contractCompareEntity.setFormType(contractCompareDTO.getFormType());
        contractCompareEntity.setCompareStatus(compareStatus);
        //合同比对结果页新建的比对都是本地上传的,没有dataId
        if (!Objects.equals(formType, ContractCompareFormTypeEnum.LOCAL_UPLOAD)) {
            contractCompareEntity.setStandardDataId(contractCompareDTO.getCompareList().get(0).getDataId());
            contractCompareEntity.setCompareDataId(contractCompareDTO.getCompareList().get(1).getDataId());
        }
        contractCompareEntity.setCreatorId(contractCompareDTO.getUserId());
        contractCompareEntity.setDel(DelEnum.NORMAL.getDel());
        try {
            contractCompareModel.insert(contractCompareEntity);
        } catch (Exception e) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }
        try {
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setIndex(IndexTypeEnum.IDX_CONTRACT_COMPARE.getIndex());
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_CONTRACT_COMPARE);
            insertDTO.setEsId(contractCompareDTO.getCorpid() + "_"+ contractCompareEntity.getId());
            insertDTO.setWaitUntil(WriteRequest.RefreshPolicy.WAIT_UNTIL);
            Map<String, Object> source = BeanUtil.convertBean2Map(contractCompareEntity, true, true);
            insertDTO.setSource(source);
            insertDTO.setParent(null);
            paasEsModel.insert(insertDTO);
        } catch (Exception e) {
            LOG.error("es插入报错",e);
            LOG.error(contractCompareEntity.toString());
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        String corpid = null;
        String userId = null;
        try {
            corpid = contractCompareDTO.getCorpid();
            userId = contractCompareDTO.getUserId();
            PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.CONTRACT_COMPARE.getAlias(), corpid);
            // 首次试用初始化菜单
            if (Objects.isNull(paasAppEntity)){
                LOG.info("-------------contractCompare init start");
                MenuInitDTO menuInitDTO = new MenuInitDTO();
                AppModuleEntity appModule = appModuleModel.getByAlias(SystemAppMenuEnum.CONTRACT_COMPARE.getAlias());
                if (Objects.isNull(appModule)){
                    throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620001);
                }
                menuInitDTO.setName(appModule.getName());
                menuInitDTO.setIcon(appModule.getIcon());
                menuInitDTO.setAlias(XbbRefTypeEnum.CONTRACT_COMPARE.getAlias());
                BeanUtil.copyProperties(contractCompareDTO, menuInitDTO);
                initMenuHelp.menuInit(menuInitDTO);
                LOG.info("-------------contractCompare init end");
            }
        } catch (XbbException e) {
            LOG.error("contractCompare init error",e);
        }
        // 记录日志
        List<ComparePoJo> compareList = contractCompareDTO.getCompareList();
        UserEntity userEntity = userModel.getByKey(contractCompareDTO.getUserId(), contractCompareDTO.getCorpid());
        CompanyEntity companyEntity = companyModel.getByKey(corpid);
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_CONTRACT_COMPARE), userEntity.getName(), compareList.get(0).getFileName(), compareList.get(1).getFileName());
        mongoLogHelp.saveLoggerByInsert(corpid, userId, userEntity.getName(), companyEntity.getCorpName(), memo, userId, contractCompareDTO.getHttpHeader(), OperateModuleTypeEnum.CONTRACTCOMPARE,OperateTypeEnum.CONTRACTCOMPARE);
        if (Objects.equals(compareStatus, ContractCompareStatusEnum.FAILURE.getCode())) {
            ContractCompareThirdPartyErrorEnum thirdPartyErrorEnum = ContractCompareThirdPartyErrorEnum.getByCode(resultJson.getInteger("code"));
            if (Objects.nonNull(thirdPartyErrorEnum)) {
                LOG.error(corpid + ContractCompareErrorCodeEnum.API_ERROR_1620006.getCode() + thirdPartyErrorEnum.getMemo());
                throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620006.getCode(), thirdPartyErrorEnum.getMemo());
            } else {
                LOG.error(corpid + ContractCompareErrorCodeEnum.API_ERROR_1620006.getCode() + resultJson.getString("message"));
                throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620006.getCode(), resultJson.getString("message"));
            }
        }

        ContractCompareUrlPojo contractCompareUrlPojo = new ContractCompareUrlPojo();
        contractCompareUrlPojo.setContractCompareId(contractCompareEntity.getId());
        contractCompareUrlPojo.setUrlOpenSource(ContractCompareUrlOpenEnum.START_COMPARE.getCode());
        String resultCrmUrl = contractCompareUtil.packagingCompareResultUrlToCrmUrl(contractCompareUrlPojo);
        jsonObject.put("resultUrl", resultCrmUrl);

        return jsonObject;
    }




    @Override
    public CabinetFileListGetVO fileSelect(ContractCompareFileSelectDTO contractCompareFileSelectDTO) throws XbbException {
        String corpid = contractCompareFileSelectDTO.getCorpid();
        String userId = contractCompareFileSelectDTO.getUserId();
        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);
        Boolean inApproval = contractCompareFileSelectDTO.getInApproval();
        CabinetFileListGetVO cabinetFileListGetVO = new CabinetFileListGetVO();
        LinkedList<CabinetFilePojo> filePojoList = new LinkedList<>();
        //把对于该用户可见的附件字段放入canSeeFileAttrList
        List<String> canSeeFileAttrList = new ArrayList<>();
        //文件柜可见权限校验
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
        verifyViewPermissionDTO.setSaasMark(contractCompareFileSelectDTO.getSaasMark());
        verifyViewPermissionDTO.setLoginUser(contractCompareFileSelectDTO.getLoginUser());
        verifyViewPermissionDTO.setBusinessType(contractCompareFileSelectDTO.getBusinessType());
        boolean canSee = ProPermissionHelp.verifyFileVisiblePermission(verifyViewPermissionDTO);
        if (inApproval && !openWorkFlow) {
            //判断是否启用审批节点中的字段权限
            PaasProcessTemplateNodeEntityExt processTemplateNodeEntityExt = paasProcessTemplateNodeModel.getByKey(contractCompareFileSelectDTO.getTemplateNodeId(), corpid);
            PaasProcessTemplateEntityExt processTemplateEntityExt = paasProcessTemplateModel.getByKey(processTemplateNodeEntityExt.getTemplateId(), corpid);
            PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(contractCompareFileSelectDTO.getProcessTaskId(), corpid);

            List<FieldPermissionEntityExt> fieldPermissionList = processTemplateNodeEntityExt.getFieldPermissionList();
            //过滤出是附件的字段
            List<FieldPermissionEntityExt> fieldPermissionEntityExtList = fieldPermissionList.stream().filter(fieldPermissionEntityExt -> (Objects.equals(fieldPermissionEntityExt.getFieldType(), FieldTypeEnum.UPLOAD.getType())
                    ||Objects.equals(fieldPermissionEntityExt.getFieldType(), FieldTypeEnum.TEMPLATE_FIELD.getType()))
                    && Objects.equals(fieldPermissionEntityExt.getVisible(), 1)).collect(Collectors.toList());
            for (FieldPermissionEntityExt fieldPermissionEntityExt : fieldPermissionEntityExtList) {
                String attr = fieldPermissionEntityExt.getAttr();
                //添加子表单中可见的附件字段
                if (attr.startsWith("subForm") && fieldPermissionEntityExt.getSubAttr().startsWith("file")) {
                    canSeeFileAttrList.add(attr + "." + fieldPermissionEntityExt.getSubAttr());
                } else {
                    canSeeFileAttrList.add(attr);
                }
            }

            JSONObject data = JSONObject.parseObject(paasProcessDataEntity.getData());
            collectFiles(corpid,data, canSeeFileAttrList, filePojoList, inApproval, paasProcessDataEntity, null);
            //编辑进审批的话需要查文件柜
            if (Objects.equals(paasProcessDataEntity.getFormDataId(), 0L)) {
                Long id = 1L;
                for (CabinetFilePojo cabinetFilePojo : filePojoList) {
                    cabinetFilePojo.setId(id++);
                }
            }
            //formDataId!=0,说明不是新建进审批的
            if (!Objects.equals(paasProcessDataEntity.getFormDataId(), 0L) && canSee) {
                Map<String, Object> params = new HashMap<>(4);
                params.put(StringConstant.CORPID, corpid);
                params.put("dataIdIn", Collections.singletonList(contractCompareFileSelectDTO.getDataId()));
                params.put("businessType", contractCompareFileSelectDTO.getBusinessType());
                params.put("del", DelEnum.NORMAL.getDel());
                List<CabinetFileEntity> fileEntityList = cabinetFileModel.findEntitys(params);
                Set<String> userIdSet = fileEntityList.stream().map(CabinetFileEntity::getUserId).collect(Collectors.toSet());
                List<UserEntity> userList = userModel.getByUserIdIn(corpid, userIdSet);
                Map<String, String> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
                Long id = 1L;
                label:for (CabinetFileEntity cabinetFileEntity : fileEntityList) {
                    String ext = cabinetFileEntity.getExt();
                    String attachIndex = cabinetFileEntity.getAttachIndex();
                    List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
                    if (!supportedFileTypeList.contains(ext)) {
                        continue;
                    }
                    ListIterator<CabinetFilePojo> it = filePojoList.listIterator();
                    while (it.hasNext()) {
                        CabinetFilePojo cabinetFilePojo = it.next();
                        if (Objects.equals(cabinetFilePojo.getAttachIndex(), attachIndex)) {
                            cabinetFilePojo.setId(id++);
                            cabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                            cabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                            continue label;
                        }

                    }
                    CabinetFilePojo newCabinetFilePojo = new CabinetFilePojo();
                    newCabinetFilePojo.setId(id++);
                    newCabinetFilePojo.setAttachIndex(attachIndex);
                    newCabinetFilePojo.setFilename(cabinetFileEntity.getFilename());
                    newCabinetFilePojo.setExt(ext);
                    newCabinetFilePojo.setSize(cabinetFileEntity.getSize());
                    newCabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                    newCabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                    filePojoList.addFirst(newCabinetFilePojo);
                }
            }
            cabinetFileListGetVO.setFiles(filePojoList);
            return cabinetFileListGetVO;
        } else if (inApproval && openWorkFlow) {
            //判断是否启用审批节点中的字段权限
            WorkflowNodeEntity workflowNodeEntity = workflowNodeModel.getByKey(Long.valueOf(contractCompareFileSelectDTO.getTemplateNodeId().toString()), corpid);
            WorkflowEntity workflowEntity = workflowModel.getByKey(workflowNodeEntity.getWorkflowId(), corpid);
            WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(contractCompareFileSelectDTO.getProcessTaskId(), corpid);
            Integer operate = workflowTransferDataEntity.getOperate();

            JSONObject fieldPermission = JSONObject.parseObject(workflowNodeEntity.getConfigData()).getJSONObject("fieldPermission");
            //过滤出是附件的字段
            for (String key : fieldPermission.keySet()) {
                JSONObject field = fieldPermission.getJSONObject(key);
                if ((Objects.equals(field.getInteger("fieldType"), FieldTypeEnum.UPLOAD.getType())||Objects.equals(field.getInteger("fieldType"), FieldTypeEnum.TEMPLATE_FIELD.getType()
                )) && Objects.nonNull(field.getInteger("visible")) && Objects.equals(field.getInteger("visible"), 1)) {
                    //工作流中子表单的附件字段的key存的是subForm_X.file_X,所以直接拿
                    canSeeFileAttrList.add(key);
                }
            }

            JSONObject data = workflowTransferDataEntity.getData().getJSONObject("data").getJSONObject("data");
            collectFiles(corpid,data, canSeeFileAttrList, filePojoList, inApproval, null, workflowTransferDataEntity);
            //编辑进审批的话需要查文件柜
            if (Objects.equals(operate, OperateTypeEnum.NEW.getCode())) {
                Long id = 1L;
                for (CabinetFilePojo cabinetFilePojo : filePojoList) {
                    cabinetFilePojo.setId(id++);
                }
            }
            if (!Objects.equals(operate, OperateTypeEnum.NEW.getCode()) && canSee) {
                Map<String, Object> params = new HashMap<>(4);
                params.put(StringConstant.CORPID, corpid);
                params.put("dataIdIn", Collections.singletonList(contractCompareFileSelectDTO.getDataId()));
                params.put("businessType", contractCompareFileSelectDTO.getBusinessType());
                params.put("del", DelEnum.NORMAL.getDel());
                List<CabinetFileEntity> fileEntityList = cabinetFileModel.findEntitys(params);
                Set<String> userIdSet = fileEntityList.stream().map(CabinetFileEntity::getUserId).collect(Collectors.toSet());
                List<UserEntity> userList = userModel.getByUserIdIn(corpid, userIdSet);
                Map<String, String> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
                Long id = 1L;
                label:for (CabinetFileEntity cabinetFileEntity : fileEntityList) {
                    String ext = cabinetFileEntity.getExt();
                    String attachIndex = cabinetFileEntity.getAttachIndex();
                    List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
                    if (!supportedFileTypeList.contains(ext)) {
                        continue;
                    }
                    ListIterator<CabinetFilePojo> it = filePojoList.listIterator();
                    while (it.hasNext()) {
                        CabinetFilePojo cabinetFilePojo = it.next();
                        if (Objects.equals(cabinetFilePojo.getAttachIndex(), attachIndex)) {
                            cabinetFilePojo.setId(id++);
                            cabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                            cabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                            continue label;
                        }

                    }
                    CabinetFilePojo newCabinetFilePojo = new CabinetFilePojo();
                    newCabinetFilePojo.setId(id++);
                    newCabinetFilePojo.setAttachIndex(attachIndex);
                    newCabinetFilePojo.setFilename(cabinetFileEntity.getFilename());
                    newCabinetFilePojo.setExt(ext);
                    newCabinetFilePojo.setSize(cabinetFileEntity.getSize());
                    newCabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                    newCabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                    filePojoList.addFirst(newCabinetFilePojo);
                }
            }

            cabinetFileListGetVO.setFiles(filePojoList);
            return cabinetFileListGetVO;
        }




        PaasFormExplainEntity formExplain = paasFormExplainModel.getByFormId(contractCompareFileSelectDTO.getFormId(), corpid);
        ContractEntityExt contractEntityExt = null;
        PurchaseEntityExt purchaseEntityExt = null;
        List<String> ownerUserIdList = null;
        List<String> coUserUserIdList = null;
        if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), contractCompareFileSelectDTO.getBusinessType())) {
            List<ContractUserEntity> contractUserList = contractUserModel.getContractUserList(corpid, contractCompareFileSelectDTO.getDataId(), null);
            ownerUserIdList = contractUserList.stream().filter(item -> Objects.equals(item.getIsMain(), 1)).map(ContractUserEntity::getUserId).collect(Collectors.toList());
            coUserUserIdList = contractUserList.stream().filter(item -> Objects.equals(item.getIsMain(), 0)).map(ContractUserEntity::getUserId).collect(Collectors.toList());
            contractEntityExt = contractModel.getByKey(contractCompareFileSelectDTO.getDataId(), corpid);
            cabinetFileListGetVO.setLinkName(contractEntityExt.getData().getString(ContractEnum.NAME.getAttr()));
        } else if (Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(), contractCompareFileSelectDTO.getBusinessType())) {
            List<PurchaseUserEntity> purchaseUserList = purchaseUserModel.getPurchaseUserListByPurchaseId(corpid, contractCompareFileSelectDTO.getDataId(), null);
            ownerUserIdList = purchaseUserList.stream().filter(item -> Objects.equals(item.getIsMain(), 1)).map(PurchaseUserEntity::getUserId).collect(Collectors.toList());
            coUserUserIdList = purchaseUserList.stream().filter(item -> Objects.equals(item.getIsMain(), 0)).map(PurchaseUserEntity::getUserId).collect(Collectors.toList());
            purchaseEntityExt = purchaseModel.getByKey(contractCompareFileSelectDTO.getDataId(), corpid);
            cabinetFileListGetVO.setLinkName(purchaseEntityExt.getData().getString(PurchaseEnum.PURCHASE_NAME.getAttr()));
        }
        JSONObject data = null;
        JSONArray explainArray = JSONObject.parseArray(formExplain.getExplains());
        for (Object fieldExplain : explainArray) {
            JSONObject fieldExplainJson = (JSONObject) JSONObject.toJSON(fieldExplain);
            if ((Objects.equals(fieldExplainJson.getInteger("fieldType"), FieldTypeEnum.UPLOAD.getType())
                    ||Objects.equals(fieldExplainJson.getInteger("fieldType"), FieldTypeEnum.TEMPLATE_FIELD.getType()))
                    && Objects.equals(fieldExplainJson.getInteger("visible"), 1)) {
                if (Objects.equals(fieldExplainJson.getInteger("visibleScopeEnable"), 1)) {
                    //判断这个字段对于这个用户是否可见开始
                    FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                    fieldAttrEntity.setVisibleScopeEnable(fieldExplainJson.getInteger("visibleScopeEnable"));
                    VisibleRulePoJo visibleScopeRule = JSONObject.toJavaObject(fieldExplainJson.getJSONObject("visibleScopeRule"), VisibleRulePoJo.class);
                    fieldAttrEntity.setVisibleScopeRule(visibleScopeRule);

                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                    handlerExplainDTO.setLoginUser(contractCompareFileSelectDTO.getLoginUser());
                    handlerExplainDTO.setUserId(userId);
                    for (Integer relative : visibleScopeRule.getRelative()) {
                        if (Objects.equals(relative, RelatedPersonnelEnum.OWNER.getType())) {
                            handlerExplainDTO.setOwnerId(ownerUserIdList);
                        } else if (Objects.equals(relative, RelatedPersonnelEnum.CREATOR.getType())) {
                            if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), contractCompareFileSelectDTO.getBusinessType())) {
                                handlerExplainDTO.setCreatorId(contractEntityExt.getCreatorId());
                            } else if (Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(), contractCompareFileSelectDTO.getBusinessType())) {
                                handlerExplainDTO.setCreatorId(purchaseEntityExt.getCreatorId());
                            }
                        } else if (Objects.equals(relative, RelatedPersonnelEnum.CO_USER.getType())) {
                            handlerExplainDTO.setCoUserId(coUserUserIdList);
                        }
                    }
                    Boolean invisibleOfScope = ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO);
                    if (!invisibleOfScope) {
                        canSeeFileAttrList.add(fieldExplainJson.getString("attr"));
                    }
                } else {
                    canSeeFileAttrList.add(fieldExplainJson.getString("attr"));
                }
                //判断这个字段对于这个用户是否可见开始结束
                //添加子表单中可见的附件字段
            } else if (Objects.equals(fieldExplainJson.getInteger("fieldType"), FieldTypeEnum.SUB_FORM.getType()) && Objects.equals(fieldExplainJson.getInteger("visible"), 1)) {
                if (Objects.equals(fieldExplainJson.getInteger("visibleScopeEnable"), 1)) {
                    //判断子表单对于该用户是否可见开始
                    FieldAttrEntity fieldAttrEntity1 = new FieldAttrEntity();
                    fieldAttrEntity1.setVisibleScopeEnable(fieldExplainJson.getInteger("visibleScopeEnable"));
                    VisibleRulePoJo visibleScopeRule1 = JSONObject.toJavaObject(fieldExplainJson.getJSONObject("visibleScopeRule"), VisibleRulePoJo.class);
                    fieldAttrEntity1.setVisibleScopeRule(visibleScopeRule1);

                    HandlerExplainDTO handlerExplainDTO1 = new HandlerExplainDTO();
                    handlerExplainDTO1.setLoginUser(contractCompareFileSelectDTO.getLoginUser());
                    handlerExplainDTO1.setUserId(userId);
                    for (Integer relative : visibleScopeRule1.getRelative()) {
                        if (Objects.equals(relative, RelatedPersonnelEnum.OWNER.getType())) {
                            handlerExplainDTO1.setOwnerId(ownerUserIdList);
                        } else if (Objects.equals(relative, RelatedPersonnelEnum.CREATOR.getType())) {
                            handlerExplainDTO1.setCreatorId(contractEntityExt.getCreatorId());
                        } else if (Objects.equals(relative, RelatedPersonnelEnum.CO_USER.getType())) {
                            handlerExplainDTO1.setCoUserId(coUserUserIdList);
                        }
                    }
                    Boolean subFormInvisibleOfScope = ExplainUtil.invisibleOfScope(fieldAttrEntity1, handlerExplainDTO1);
                    //不可见跳,到下一个字段
                    if (!subFormInvisibleOfScope) {
                        continue;
                    }
                }
                //判断子表单对于该用户是否可见结束
                //添加子表单中对于该用户可见的附件字段
                for (Object item : fieldExplainJson.getJSONObject("subForm").getJSONArray("items")) {
                    JSONObject itemJson = (JSONObject) JSONObject.toJSON(item);
                    if ((Objects.equals(itemJson.getInteger("fieldType"), FieldTypeEnum.UPLOAD.getType())
                            ||Objects.equals(itemJson.getInteger("fieldType"), FieldTypeEnum.TEMPLATE_FIELD.getType()))
                            && Objects.equals(itemJson.getInteger("visible"), 1)) {
                        if (Objects.equals(fieldExplainJson.getInteger("visibleScopeEnable"), 1)) {
                            //判断子表单中的附件字段对于该用户是否可见开始
                            FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                            fieldAttrEntity.setVisibleScopeEnable(itemJson.getInteger("visibleScopeEnable"));
                            VisibleRulePoJo visibleScopeRule = JSONObject.toJavaObject(itemJson.getJSONObject("visibleScopeRule"), VisibleRulePoJo.class);
                            fieldAttrEntity.setVisibleScopeRule(visibleScopeRule);
                            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                            handlerExplainDTO.setLoginUser(contractCompareFileSelectDTO.getLoginUser());
                            handlerExplainDTO.setUserId(userId);
                            for (Integer relative : visibleScopeRule.getRelative()) {
                                if (Objects.equals(relative, RelatedPersonnelEnum.OWNER.getType())) {
                                    handlerExplainDTO.setOwnerId(ownerUserIdList);
                                } else if (Objects.equals(relative, RelatedPersonnelEnum.CREATOR.getType())) {
                                    handlerExplainDTO.setCreatorId(contractEntityExt.getCreatorId());
                                } else if (Objects.equals(relative, RelatedPersonnelEnum.CO_USER.getType())) {
                                    handlerExplainDTO.setCoUserId(coUserUserIdList);
                                }
                            }
                            Boolean invisibleOfScope = ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO);
                            if (!invisibleOfScope) {
                                //这里要和审批中的子表单中的附件字段区分,子表单数据表中存的数据格式和审批数据表中存的子表单数据格式不一样,collectFiles()方法中子表单数据表中存的数据进入第一个if中处理
                                canSeeFileAttrList.add("subFormData." + itemJson.getString("attr"));
                            }
                            //判断子表单中的附件字段对于该用户是否可见结束
                        } else {
                            canSeeFileAttrList.add("subFormData." + itemJson.getString("attr"));
                        }
                    }
                }
            }


            if (Objects.nonNull(contractEntityExt)) {
                data = contractEntityExt.getData();
                List<? extends PaasFormSubDataEntity> contractSubDataList = contractSubDataModel.getByDataId(contractCompareFileSelectDTO.getDataId(), corpid);
                //将子表单数据表中附件字段塞入主表的data,这样就可以使用collectFiles()方法了
                for (PaasFormSubDataEntity contractSubDataEntity : contractSubDataList) {
                    String attr = contractSubDataEntity.getAttr();
                    if (attr.startsWith("subForm")) {
                        JSONObject subData = (JSONObject) JSONObject.toJSON(contractSubDataEntity.getData());
                        for (String key : subData.keySet()) {
                            if (key.startsWith("file")) {
                                String subFileAttr = "subFormData." + key + ':'+ contractSubDataEntity.getId();
                                String value = subData.getString(key);
                                if (value != null) {
                                    data.put(subFileAttr, value);
                                }
                            }
                        }
                    }
                }
            } else if (Objects.nonNull(purchaseEntityExt)) {
                data = purchaseEntityExt.getData();
                List<? extends PaasFormSubDataEntity> purchaseSubDataList = purchaseSubDataModel.getByDataId(contractCompareFileSelectDTO.getDataId(), corpid);
                //将子表单数据表中附件字段塞入主表的data,这样就可以使用collectFiles()方法了
                for (PaasFormSubDataEntity purchaseSubDataEntity : purchaseSubDataList) {
                    String attr = purchaseSubDataEntity.getAttr();
                    if (attr.startsWith("subForm")) {
                        JSONObject subData = (JSONObject) JSONObject.toJSON(purchaseSubDataEntity.getData());
                        for (String key : subData.keySet()) {
                            String subFileAttr = "subFormData." + key + ':'+ purchaseSubDataEntity.getId();
                            if (key.startsWith("file") && canSeeFileAttrList.contains(subFileAttr)) {
                                String value = subData.getString(key);
                                if (value != null) {
                                    data.put(subFileAttr, value);
                                }
                            }
                        }
                    }
                }
            }



        }
        collectFiles(corpid,data, canSeeFileAttrList, filePojoList, inApproval, null, null);
        //文件柜

        if (canSee) {
            Map<String, Object> params = new HashMap<>(4);
            params.put(StringConstant.CORPID, corpid);
            params.put("dataIdIn", Collections.singletonList(contractCompareFileSelectDTO.getDataId()));
            params.put("businessType", contractCompareFileSelectDTO.getBusinessType());
            params.put("del", DelEnum.NORMAL.getDel());
            List<CabinetFileEntity> fileEntityList = cabinetFileModel.findEntitys(params);
            Set<String> userIdSet = fileEntityList.stream().map(CabinetFileEntity::getUserId).collect(Collectors.toSet());
            List<UserEntity> userList = userModel.getByUserIdIn(corpid, userIdSet);
            Map<String, String> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
            label:for (CabinetFileEntity cabinetFileEntity : fileEntityList) {
                String ext = cabinetFileEntity.getExt();
                String attachIndex = cabinetFileEntity.getAttachIndex();
                List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
                if (!supportedFileTypeList.contains(ext)) {
                    continue;
                }
                ListIterator<CabinetFilePojo> it = filePojoList.listIterator();
                while (it.hasNext()) {
                    CabinetFilePojo cabinetFilePojo = it.next();
                    if (Objects.equals(cabinetFilePojo.getAttachIndex(), attachIndex)) {
                        cabinetFilePojo.setId(cabinetFileEntity.getId());
                        cabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                        cabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                        continue label;
                    }
                }
                CabinetFilePojo newCabinetFilePojo = new CabinetFilePojo();
                newCabinetFilePojo.setId(cabinetFileEntity.getId());
                newCabinetFilePojo.setAttachIndex(attachIndex);
                newCabinetFilePojo.setFilename(cabinetFileEntity.getFilename());
                newCabinetFilePojo.setExt(ext);
                newCabinetFilePojo.setSize(cabinetFileEntity.getSize());
                newCabinetFilePojo.setUserName(userMap.get(cabinetFileEntity.getUserId()));
                newCabinetFilePojo.setAddTime(cabinetFileEntity.getAddTime());
                filePojoList.add(newCabinetFilePojo);
            }
        } else {
            Map<String, Object> params = new HashMap<>(4);
            params.put(StringConstant.CORPID, corpid);
            params.put("dataIdIn", Collections.singletonList(contractCompareFileSelectDTO.getDataId()));
            params.put("businessType", contractCompareFileSelectDTO.getBusinessType());
            params.put("del", DelEnum.NORMAL.getDel());
            List<CabinetFileEntity> fileEntityList = cabinetFileModel.findEntitys(params);
            for (CabinetFilePojo cabinetFilePojo : filePojoList) {
                for (CabinetFileEntity cabinetFileEntity : fileEntityList) {
                    if (Objects.equals(cabinetFilePojo.getAttachIndex(), cabinetFileEntity.getAttachIndex())) {
                        cabinetFilePojo.setId(cabinetFileEntity.getId());
                    }
                }
            }
        }


        cabinetFileListGetVO.setFiles(filePojoList);
        return cabinetFileListGetVO;
    }

    @Override
    public CabinetFileListGetVO getRefusedfile(ContractCompareRefusedFileSelectDTO refusedFileSelectDTO) throws XbbException {
        CabinetFileListGetVO cabinetFileListGetVO = new CabinetFileListGetVO();
        String corpid = refusedFileSelectDTO.getCorpid();
        Long templateNodeId = refusedFileSelectDTO.getTemplateNodeId();
        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);
        LinkedList<CabinetFilePojo> filePojoList = new LinkedList<>();
        // 非工作流直接返回
        if (!openWorkFlow){
            return cabinetFileListGetVO;
        }
        WorkflowNodeEntity workflowNodeEntity = workflowNodeModel.getByKey(templateNodeId, corpid);
        JSONObject fieldPermission = JSONObject.parseObject(workflowNodeEntity.getConfigData()).getJSONObject("fieldPermission");
        if (Objects.isNull(fieldPermission)){
            return cabinetFileListGetVO;
        }
        Long formId = workflowNodeEntity.getFormId();
        // 可见字段集合
        List<String> canSeeFileAttrList = new ArrayList<>();
        // 取出可见的附件字段
        for (String key : fieldPermission.keySet()) {
            JSONObject field = fieldPermission.getJSONObject(key);
            Integer fieldType = field.getInteger("fieldType");
            Integer visible = field.getInteger("visible");
            if (Objects.isNull(visible) || Objects.isNull(fieldType) || (!Objects.equals(fieldType, FieldTypeEnum.UPLOAD.getType()) && !Objects.equals(fieldType, FieldTypeEnum.TEMPLATE_FIELD.getType()))){
                continue;
            }
            if (Objects.equals(visible,1)){
                /**
                 *    "file_1" 或者 "subForm_3.file_1"
                 */
                canSeeFileAttrList.add(key);
            }
        }
        if (CollectionUtils.isEmpty(canSeeFileAttrList)){
            return cabinetFileListGetVO;
        }

        // 查询出该条数据最近7条被拒工作流
        Map<String, Object> params = new HashMap<>();
        params.put(StringConstant.CORPID, corpid);
        params.put("dataId", refusedFileSelectDTO.getDataId());
        params.put("flowStatus",FlowStatusEnum.REJECT.getType());
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        params.put(StringConstant.BUSINESS_TYPE, refusedFileSelectDTO.getBusinessType());
        params.put("start",BasicConstant.ZERO);
        params.put("pageNum",BasicConstant.SEVEN);
        params.put("orderByStrDesc","update_time");
        List<WorkflowTaskEntity> workflowTaskEntities = workflowTaskModel.findEntities(params);
        if (CollectionUtils.isEmpty(workflowTaskEntities)){
            return cabinetFileListGetVO;
        }
        ArrayList<Long> taskIdIn = new ArrayList<>();
        workflowTaskEntities.forEach(item -> taskIdIn.add(item.getId()));
        // 取出对应的数据
        params.clear();
        params.put(StringConstant.CORPID, corpid);
        params.put("taskIdIn", taskIdIn);
//        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<WorkflowTransferDataEntity> workflowTransferDataEntities = workflowTransferDataModel.findEntities(params);
        if (CollectionUtils.isEmpty(workflowTransferDataEntities)){
            LOG.error("--------workflowTransferDataEntities is null");
            return cabinetFileListGetVO;
        }
        Map<Long, WorkflowTransferDataEntity> dataMap = new HashMap<>();
        workflowTransferDataEntities.forEach(item -> dataMap.put(item.getTaskId(),item));
        AtomicLong atomicLong = new AtomicLong();
        atomicLong.set(100000000000000L);
        // qu对应附件
        List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
        for (WorkflowTaskEntity workflowTaskEntity : workflowTaskEntities) {
            getWorkFlowRefusedFile(corpid,formId,supportedFileTypeList, workflowTaskEntity.getId(), filePojoList, dataMap, workflowTaskEntity.getUpdateTime(), atomicLong);
        }

        cabinetFileListGetVO.setFiles(filePojoList);
        return cabinetFileListGetVO;
    }



    public void getWorkFlowRefusedFile(String corpid,Long formId,List<String> supportedFileTypeList, Long workflowTaskId, LinkedList<CabinetFilePojo> filePojoList, Map<Long, WorkflowTransferDataEntity> dataMap, Long updateTime, AtomicLong atomicLong) throws XbbException{

        WorkflowTransferDataEntity workflowTransferDataEntity = dataMap.get(workflowTaskId);
        if (Objects.isNull(workflowTransferDataEntity)){
            LOG.error("workflowTransferDataEntity is null");
            return;
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        String explains = paasFormExplainEntity.getExplains();
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
        JSONObject data = workflowTransferDataEntity.getData().getJSONObject("data").getJSONObject("data");
        List<Map<String, String>> fileList = new ArrayList<>();
        for (String key : data.keySet()) {
            FieldAttrEntity fieldAttrEntity = explainMap.get(key);
            if(fieldAttrEntity==null){
                continue;
            }
            Integer fieldType = fieldAttrEntity.getFieldType();
            if(Objects.equals(fieldType,FieldTypeEnum.TEMPLATE_FIELD.getType())) {
                // 在线编辑字段
                String fileString = data.getString(key);
                if(StringUtil.isEmpty(fileString)){
                    continue;
                }
                fileString = fileString.replaceAll("\\\\", "");
                TemplateFieldValuePojo templateFieldValuePojo = JSONObject.parseObject(fileString, TemplateFieldValuePojo.class);
                String contractEditFileId = templateFieldValuePojo.getContract_edit_file_id();
                Integer contractEditFileVersion = templateFieldValuePojo.getContract_edit_file_version();
                Map<String, String> tempMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                tempMap.put("fileId", contractEditFileId);
                tempMap.put("fileVersion", contractEditFileVersion.toString());
                fileList.add(tempMap);
            }
        }

        List<ContractEditFileEntity> contractEditFileEntityList = contractEditFileModel.getByFileIdAndFileVersion(corpid, fileList);
        Map<String,ContractEditFileEntity> contractEditFileEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(contractEditFileEntityList)){
            contractEditFileEntityList.forEach(item->{
                contractEditFileEntityMap.put(item.getFileId()+"-"+item.getFileVersion(),item);
            });
        }

        for (String key : data.keySet()) {
            FieldAttrEntity fieldAttrEntity = explainMap.get(key);
            if(fieldAttrEntity!=null && fieldAttrEntity.getFieldType()!=null && Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.TEMPLATE_FIELD.getType())){
                // 在线编辑字段
                String fileString = data.getString(key);
                if(StringUtil.isEmpty(fileString)){
                    continue;
                }
                TemplateFieldValuePojo templateFieldValuePojo = JSONObject.parseObject(fileString, TemplateFieldValuePojo.class);
                String contractEditFileId = templateFieldValuePojo.getContract_edit_file_id();
                Integer contractEditFileVersion = templateFieldValuePojo.getContract_edit_file_version();

                ContractEditFileEntity contractEditFileEntity = contractEditFileEntityMap.get(contractEditFileId + "-" + contractEditFileVersion);
                CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
                cabinetFilePojo.setId(atomicLong.addAndGet(1));
                cabinetFilePojo.setAttachIndex(contractEditFileEntity.getFileUrl());
                cabinetFilePojo.setFilename(contractEditFileEntity.getFileName());
                cabinetFilePojo.setExt(contractEditFileEntity.getFileExt());
                cabinetFilePojo.setSize(Integer.parseInt(contractEditFileEntity.getFileSize().toString()));
//                cabinetFilePojo.setUserName(userName);
                cabinetFilePojo.setAddTime(contractEditFileEntity.getUpdateTime());
                filePojoList.add(cabinetFilePojo);

            }else if (key.startsWith("file")){
                JSONArray jsonArray = data.getJSONArray(key);
                if (CollectionUtils.isEmpty(jsonArray)){
                    continue;
                }
                JSONObject file = (JSONObject)jsonArray.get(0);
                String ext = file.getString("ext");
                if (!supportedFileTypeList.contains(ext)) {
                    continue;
                }
                CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
                cabinetFilePojo.setId(atomicLong.addAndGet(1));
                cabinetFilePojo.setAttachIndex(file.getString("attachIndex"));
                cabinetFilePojo.setFilename(file.getString("filename"));
                cabinetFilePojo.setExt(ext);
                cabinetFilePojo.setSize(file.getInteger("size"));
//                cabinetFilePojo.setUserName(userName);
                cabinetFilePojo.setAddTime(updateTime);
                filePojoList.add(cabinetFilePojo);
            } else if (key.startsWith("subForm")){
                JSONArray jsonArray = data.getJSONArray(key);
                if (jsonArray.isEmpty()){
                    continue;
                }
                for (Object o : jsonArray) {
                    JSONObject jsonObject = (JSONObject) o;
                    for (String s : jsonObject.keySet()) {
                        if (!s.startsWith("file")){
                            continue;
                        }
                        JSONArray value = jsonObject.getJSONArray(s);
                        if (CollectionUtils.isEmpty(value)){
                            continue;
                        }
                        JSONObject file = (JSONObject)value.get(0);
                        if (s.startsWith("file") && Objects.nonNull(file)){
                            String ext = file.getString("ext");
                            if (!supportedFileTypeList.contains(ext)) {
                                continue;
                            }
                            CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
                            cabinetFilePojo.setId(atomicLong.addAndGet(1));
                            cabinetFilePojo.setAttachIndex(file.getString("attachIndex"));
                            cabinetFilePojo.setFilename(file.getString("filename"));
                            cabinetFilePojo.setExt(ext);
                            cabinetFilePojo.setSize(file.getInteger("size"));
//                        cabinetFilePojo.setUserName(userName);
                            cabinetFilePojo.setAddTime(updateTime);
                            filePojoList.add(cabinetFilePojo);
                        }
                    }
                }
            }
        }


    }


    public static void main(String[] args) {
        String loginResInfo = "{\\\"base_contract_id\\\":1,\\\"contract_edit_file_id\\\":\\\"dbaebcd91cd14a2e884f21da0747a123\\\",\\\"contract_edit_file_version\\\":2}";
        loginResInfo = loginResInfo.replaceAll("\\\\", "");
        TemplateFieldValuePojo jsonObject = JSONObject.parseObject(loginResInfo,TemplateFieldValuePojo.class);

        System.out.println(jsonObject);

    }

    @Override
    public JSONObject checkCanLocalUpload(CheckCanLocalUploadDTO checkCanLocalUploadDTO) throws XbbException {
        JSONObject result = new JSONObject();
        String corpid = checkCanLocalUploadDTO.getCorpid();
        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);
        if (!openWorkFlow) {
            PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(checkCanLocalUploadDTO.getProcessTaskId(), corpid);
            if (Objects.equals(paasProcessDataEntity.getFormDataId(), 0L)) {
                result.put("result", false);
                return result;
            }
        } else {
            WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(checkCanLocalUploadDTO.getProcessTaskId(), corpid);
            Integer operate = workflowTransferDataEntity.getOperate();
            if (Objects.equals(operate, OperateTypeEnum.NEW.getCode())) {
                result.put("result", false);
                return result;
            }
        }
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
        verifyViewPermissionDTO.setSaasMark(checkCanLocalUploadDTO.getSaasMark());
        verifyViewPermissionDTO.setLoginUser(checkCanLocalUploadDTO.getLoginUser());
        verifyViewPermissionDTO.setBusinessType(checkCanLocalUploadDTO.getBusinessType());
        boolean canSee = ProPermissionHelp.verifyFileVisiblePermission(verifyViewPermissionDTO);
        if (!canSee) {
            result.put("result", false);
            return result;
        }

        result.put("result", true);
        return result;
    }

    @Override
    public ContractCompareVO historyCompare(ContractCompareHistoryCompareDTO contractCompareHistoryCompareDTO) throws XbbException {
        List<FieldAttrEntity> headList = new ArrayList<>();
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        fieldAttrEntity.setAttr(ListOptionEnum.OPTION.getAttr());
        fieldAttrEntity.setAttrName(ListOptionEnum.OPTION.getAttrName());
        fieldAttrEntity.setFieldType(FieldTypeEnum.OPTION.getType());
        headList.add(fieldAttrEntity);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(ContractCompareEnum.values().length);
        List<String> filterFieldList = new ArrayList<>();
        filterFieldList.add(ContractCompareEnum.FORM_TYPE.getSaasAttr());
        FieldAttrHelper.createList(ContractCompareEnum.class, filterFieldList, null, headList, explainMap);
        headList.forEach(item->{
            if (Objects.equals(item.getAttr(), ContractCompareEnum.COMPARE_CONTRACT_NAME.getSaasAttr()) || Objects.equals(item.getAttr(), ContractCompareEnum.STANDARD_CONTRACT_NAME.getSaasAttr())) {
                LinkDetailPojo linkDetail = new LinkDetailPojo();
                linkDetail.setAttr(item.getAttr());
                linkDetail.setSaasMark(SaasMarkEnum.SAAS.getCode());
                item.setLinkDetail(linkDetail);
            }
        });
        ContractCompareVO contractCompareVO = new ContractCompareVO();
        contractCompareVO.setHeadList(headList);

        UserVO loginUser = contractCompareHistoryCompareDTO.getLoginUser();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser, userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity);
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ZERO,false);
        Map<String, Object> param = new HashMap<>(8);
        param.put(StringConstant.CORPID, contractCompareHistoryCompareDTO.getCorpid());
        param.put("orDataId", contractCompareHistoryCompareDTO.getDataId());
        param.put("creatorIdIn", userIdIn);
        if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), contractCompareHistoryCompareDTO.getBusinessType())) {
            param.put("formType", ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode());
        } else if (Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(), contractCompareHistoryCompareDTO.getBusinessType())) {
            param.put("formType", ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode());
        }
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Integer count = contractCompareModel.getEntityCount(param);
        PageHelper pageHelper = new PageHelper(contractCompareHistoryCompareDTO.getPage(), contractCompareHistoryCompareDTO.getPageSize());
        pageHelper.setRowsCount(count);
        contractCompareUtil.pageSet(contractCompareHistoryCompareDTO.getPage(), contractCompareHistoryCompareDTO.getPageSize(), param);
        param.put("orderByStr", "add_time desc");
        List<ContractCompareEntity> contractCompareEntityList = contractCompareModel.findEntities(param);
        Set<String> userSet = contractCompareEntityList.stream().map(ContractCompareEntity::getCreatorId).collect(Collectors.toSet());
        List<UserEntity> userList = userModel.getByUserIdIn(contractCompareHistoryCompareDTO.getCorpid(), userSet);
        Map<String, String> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
        JSONObject option_0 = new JSONObject();
        JSONObject option = new JSONObject();
        option.put("attr", "option_contract_compare");
        option.put("value", ListOptionTabEnum.VIEW.getAttrName());
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(option);
        option_0.put("value", jsonArray);
        List<ContractCompareListVO> dataList = new ArrayList<>();
        contractCompareEntityList.forEach(item->{
            ContractCompareListVO contractCompareListVO = new ContractCompareListVO();
            BeanUtil.copyProperties(item, contractCompareListVO);
            contractCompareListVO.setDataId(item.getId());
            if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode())) {
                contractCompareListVO.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                contractCompareListVO.setSubBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
            } else if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode())) {
                contractCompareListVO.setBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
                contractCompareListVO.setSubBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
            }
            contractCompareListVO.setCreatorId(userMap.get(item.getCreatorId()));
            contractCompareListVO.setOption_0(option_0);
            if (Objects.equals(item.getCompareStatus(), ContractCompareStatusEnum.SUCCESS.getCode())) {
                contractCompareListVO.setCompareStatus(ContractCompareStatusEnum.SUCCESS.getMemo());
            } else {
                contractCompareListVO.setCompareStatus(ContractCompareStatusEnum.FAILURE.getMemo());
            }
            if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.CONTRACT_ORDER.getCode())) {
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.CONTRACT_ORDER.getMemo());
            } else if (Objects.equals(item.getFormType(), ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getCode())){
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.PURCHASE_CONTRACT.getMemo());
            } else {
                contractCompareListVO.setFormType(ContractCompareFormTypeEnum.LOCAL_UPLOAD.getMemo());
            }

            ContractCompareUrlPojo contractCompareUrlPojo = new ContractCompareUrlPojo();
            contractCompareUrlPojo.setContractCompareId(item.getId());
            String resultCrmUrl = contractCompareUtil.packagingCompareResultUrlToCrmUrl(contractCompareUrlPojo);
            contractCompareListVO.setResultUrl(resultCrmUrl);

            dataList.add(contractCompareListVO);
        });
        contractCompareVO.setPaasFormDataESList(dataList);
        contractCompareVO.setPageHelper(pageHelper);
        return contractCompareVO;
    }


    private void collectFiles (String corpid,JSONObject data, List<String> canSeeFileAttrList, List<CabinetFilePojo> filePojoList, Boolean inApproval, PaasProcessDataEntity paasProcessDataEntity, WorkflowTransferDataEntity workflowTransferDataEntity) {
        String userName = null;
        Long id = 1L;
        if (inApproval && Objects.nonNull(paasProcessDataEntity)) {
            List<UserEntity> userEntityList = userModel.getByUserId(Collections.singletonList(paasProcessDataEntity.getCreatorId()), paasProcessDataEntity.getCorpid());
            if (userEntityList.size() > 0) {
                userName = userEntityList.get(0).getName();
            }
        } else if (inApproval && Objects.nonNull(workflowTransferDataEntity)) {
            userName = workflowTransferDataEntity.getData().getJSONObject("user").getString("name");
        }
        for (String key : data.keySet()) {
            String fileString = null;
            String tempKey;
            //列表页合同比对选择文件时,将子表单数据表中的附件数据塞入了主表的data,key的形式为 subFormData.file_X:ID, 此时lastIndex!=-1
            int lastIndex = key.lastIndexOf(':');
            if (lastIndex == -1) {
                tempKey = key;
            } else {
                tempKey = key.substring(0, lastIndex);
            }
            if(canSeeFileAttrList.contains(tempKey)&&tempKey.startsWith("text_")){
                // 特殊取下在线编辑字段
                collectFiles4OnlineEditor(corpid, data.getString(key), filePojoList);

            }else if (canSeeFileAttrList.contains(tempKey)) {
                fileString = data.getString(key);
                //子表单中的附件字段subFormData.file_X:ID,也进到这里处理
                if (!StringUtil.isEmpty(fileString)) {
                    //消除所有反斜杠
                    fileString.replaceAll("\\\\", "");
                    JSONArray filesArray = JSONObject.parseArray(fileString);
                    for (Object fileObject : filesArray) {
                        JSONObject files = (JSONObject) JSONObject.toJSON(fileObject);
                        String ext = files.getString("ext");
                        //过滤掉不支持的文件类型
                        List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
                        if (!supportedFileTypeList.contains(ext)) {
                            continue;
                        }
                        CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
                        cabinetFilePojo.setId(id++);
                        cabinetFilePojo.setAttachIndex(files.getString("attachIndex"));
                        cabinetFilePojo.setFilename(files.getString("filename"));
                        cabinetFilePojo.setExt(ext);
                        cabinetFilePojo.setSize(files.getInteger("size"));
                        if (inApproval && Objects.nonNull(paasProcessDataEntity)) {
                            cabinetFilePojo.setId(id++);
                            cabinetFilePojo.setUserName(userName);
                            cabinetFilePojo.setAddTime(paasProcessDataEntity.getAddTime());
                        } else if (inApproval && Objects.nonNull(workflowTransferDataEntity)) {
                            cabinetFilePojo.setId(id++);
                            cabinetFilePojo.setUserName(userName);
                            cabinetFilePojo.setAddTime(workflowTransferDataEntity.getAddTime());
                        }
                        filePojoList.add(cabinetFilePojo);
                    }
                }
                //下面的else-if是处理审批中的附件字段中的文件
            } else if (key.startsWith("subForm")) {
                JSONArray jsonArray = data.getJSONArray(key);
                if (jsonArray.size() > 0) {
                    for (Object file : jsonArray) {
                        JSONObject fileJson = (JSONObject) JSONObject.toJSON(file);
                        Set<String> keySet = fileJson.keySet();
                        for (String subKey : keySet) {
                            String attr = key + "." + subKey;
                            if (subKey.startsWith("file") && canSeeFileAttrList.contains(attr)) {
                                fileString = fileJson.getString(subKey);
                                if (!StringUtil.isEmpty(fileString)) {
                                    //消除所有反斜杠
                                    fileString.replaceAll("\\\\", "");
                                    JSONArray filesArray = JSONObject.parseArray(fileString);
                                    for (Object fileObject : filesArray) {
                                        JSONObject files = (JSONObject) JSONObject.toJSON(fileObject);
                                        String ext = files.getString("ext");
                    //                  过滤掉不支持的文件类型
                                        List<String> supportedFileTypeList = Arrays.asList(supportedFileType);
                                        if (!supportedFileTypeList.contains(ext)) {
                                            continue;
                                        }
                                        CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
                                        cabinetFilePojo.setId(id++);
                                        cabinetFilePojo.setAttachIndex(files.getString("attachIndex"));
                                        cabinetFilePojo.setFilename(files.getString("filename"));
                                        cabinetFilePojo.setExt(ext);
                                        cabinetFilePojo.setSize(files.getInteger("size"));
                                        if (inApproval && Objects.nonNull(paasProcessDataEntity)) {
                                            cabinetFilePojo.setId(id++);
                                            cabinetFilePojo.setUserName(userName);
                                            cabinetFilePojo.setAddTime(paasProcessDataEntity.getAddTime());
                                        } else if (inApproval && Objects.nonNull(workflowTransferDataEntity)) {
                                            cabinetFilePojo.setId(id++);
                                            cabinetFilePojo.setUserName(userName);
                                            cabinetFilePojo.setAddTime(workflowTransferDataEntity.getAddTime());
                                        }
                                        filePojoList.add(cabinetFilePojo);
                                    }
                                }
                            }
                        }
                    }
                }
            }

        }
    }

    private void collectFiles4OnlineEditor(String corpid,String fileString,List<CabinetFilePojo> filePojoList){
        if(StringUtil.isEmpty(fileString)){
            return;
        }
        TemplateFieldValuePojo templateFieldValuePojo = JSONObject.parseObject(fileString, TemplateFieldValuePojo.class);
        String contract_edit_file_id = templateFieldValuePojo.getContract_edit_file_id();
        Integer contract_edit_file_version = templateFieldValuePojo.getContract_edit_file_version();

        ContractEditFileEntity contractEditFileEntity = contractEditFileModel.getOneByFileIdAndFileVersion(corpid, contract_edit_file_id, contract_edit_file_version);
        String fileUrl = contractEditFileEntity.getFileUrl();
        String fileName = contractEditFileEntity.getFileName();
        String fileExt = contractEditFileEntity.getFileExt();
        long fileSize = contractEditFileEntity.getFileSize();
        String creatorId = contractEditFileEntity.getCreatorId();

        Long addTime = contractEditFileEntity.getAddTime();
        CabinetFilePojo cabinetFilePojo = new CabinetFilePojo();
        cabinetFilePojo.setId(contractEditFileEntity.getId());
        cabinetFilePojo.setAttachIndex(fileUrl);
        cabinetFilePojo.setFilename(fileName);
        cabinetFilePojo.setExt(fileExt);
        cabinetFilePojo.setSize((int)fileSize);
        if(creatorId!=null){
            UserEntity userEntity = userModel.getByKeyIngoreDel(creatorId, corpid);
            cabinetFilePojo.setUserName(userEntity.getName());
        }
        cabinetFilePojo.setAddTime(addTime);
        filePojoList.add(cabinetFilePojo);
    }

    private List<ButtonPojo> getTopPermission(ContractCompareListDTO contractCompareListDTO, List<ButtonPojo> topButtonList){
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(XbbRefTypeEnum.CONTRACT_COMPARE_RESULT.getCode());
        Set<String> permSet = contractCompareListDTO.getLoginUser().getPermSet();
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList) {
            String permission = topButtonEnum.getProPermissionAlias();
            // permission为1的按钮一直存在的或还没加权限alias
            if (!permSet.contains(permission) && !Objects.equals(permission, StringConstant.POSITIVE_NUMBER)) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(), buttonPojo);
            topButtonList.add(buttonPojo);
        }
        return topButtonList;
    }

    @Override
    public ContractCompareUserListVO getDepUserList(ContractCompareUserDTO contractCompareUserDTO) throws XbbException {
        ContractCompareUserListVO contractCompareUserListVO= new ContractCompareUserListVO();
        String corpid = contractCompareUserDTO.getCorpid();
        Long departmentId = contractCompareUserDTO.getDepartmentId();
        String nameLike = contractCompareUserDTO.getNameLike();
        UserVO loginUser = contractCompareUserDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        String s = JSONObject.toJSONString(permSet);
        if (!permSet.contains(ProPermissionAliasEnum.CONTRACT_COMPARE_MANAGE_VIEW.getAlias())){
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620002);
        }
        if (permSet.contains(ProPermissionAliasEnum.CONTRACT_COMPARE_MANAGE_EDIT.getAlias())){
            contractCompareUserListVO.setEditPermission(1);
        } else {
            contractCompareUserListVO.setEditPermission(0);
        }
        List<ContractCompareUserVO> compareUserVOList = new ArrayList<>();
        try {
            UserListDTO userListDTO = new UserListDTO();
            userListDTO.setDelIgnore(0);
            BeanUtil.copyProperties(contractCompareUserDTO, userListDTO);
            UserListVO userListVO = userService.list(userListDTO);
            List<UserVO> userList = userListVO.getUserList();

            Set<String> userIdIn = new HashSet<>();
            userList.forEach(item -> userIdIn.add(item.getUserId()));
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.LIST_SELECT_TYPE_STAFF, BasicConstant.ONE);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            List<ContractCompareUserEntity> contractCompareUserEntities = contractCompareUserModel.findEntitys(param);
            Map<String, ContractCompareUserEntity> userEntityMap = new HashMap<>(contractCompareUserEntities.size());
            contractCompareUserEntities.forEach((item) -> userEntityMap.put(item.getUserId(), item));

            for (UserVO userVO : userList) {
                ContractCompareUserVO compareUserVO = new ContractCompareUserVO();
                compareUserVO.setId(Long.valueOf(userVO.getId()));
                compareUserVO.setUserId(userVO.getUserId());
                compareUserVO.setName(userVO.getName());
                compareUserVO.setCorpid(userVO.getCorpid());
                compareUserVO.setPosition(userVO.getPosition());
                compareUserVO.setRoleConcat(userVO.getRoleConcat());
                compareUserVO.setDepartmentConcat(userVO.getDepartmentConcat());
                ContractCompareUserEntity compareUserEntity = userEntityMap.get(userVO.getUserId());
                if (Objects.nonNull(compareUserEntity)){
                    compareUserVO.setStaff(compareUserEntity.getStaff());
                } else {
                    compareUserVO.setStaff(BasicConstant.ZERO);
                }
                compareUserVOList.add(compareUserVO);
            }
            contractCompareUserListVO.setPageHelper(userListVO.getPageHelper());
            contractCompareUserListVO.setUserList(compareUserVOList);
        } catch (XbbException e){
            LOG.error("get department Info error" + e.getMessage());
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620002);
        }
        return contractCompareUserListVO;
    }

    @Override
    public ContractCompareMsgVO batchUpdateStaff(ContractCompareUpdateStaffDTO compareUpdateStaffDTO) throws XbbException {
        ContractCompareMsgVO contractCompareMsgVO = new ContractCompareMsgVO();
        Integer staff = compareUpdateStaffDTO.getStaff();
        String corpid = compareUpdateStaffDTO.getCorpid();
        UserVO loginUser = compareUpdateStaffDTO.getLoginUser();
        List<String> userIdList = compareUpdateStaffDTO.getUserIdList();
        Set<String> permSet = loginUser.getPermSet();
        // 权限判断
        if (!permSet.contains(ProPermissionAliasEnum.CONTRACT_COMPARE_MANAGE_EDIT.getAlias())){
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620004);
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("userIdIn",userIdList);
        param.put(StringConstant.DEL,BasicConstant.ZERO);
        List<ContractCompareUserEntity> compareUserEntities = contractCompareUserModel.findEntitys(param);
        Set<String> userIds = new HashSet<>();
        if (CollectionsUtil.isNotEmpty(compareUserEntities)){
            compareUserEntities.forEach(item -> {userIds.add(item.getUserId());item.setStaff(staff);});
        }
        // 取差集
        userIdList.removeAll(userIds);
        // 走插入逻辑
        if (userIdList.size() > 0){
            List<ContractCompareUserEntity> compareUserList = new ArrayList<>();
            for (String userId : userIdList) {
                ContractCompareUserEntity contractCompareUserEntity = new ContractCompareUserEntity(corpid, userId, staff);
                compareUserList.add(contractCompareUserEntity);
            }
            contractCompareUserModel.insertBatch(compareUserList);
        }
        // 批量更新
        if (userIds.size() > 0){
            contractCompareUserModel.updateBatch(compareUserEntities, corpid);
        }
        return contractCompareMsgVO;
    }

    @Override
    public ContractCompareConsumptionVO getConsumption(ContractCompareConsumptionDTO contractCompareConsumptionDTO) throws XbbException {
        ContractCompareConsumptionVO contractCompareConsumptionVO = new ContractCompareConsumptionVO();
        String corpid = contractCompareConsumptionDTO.getCorpid();
        Integer status = contractCompareUtil.getContractCompareStatus(corpid);
        if (Objects.equals(status, ContractCompareFeeStatusEnum.NO_TRIAL.getType())){
            contractCompareConsumptionVO.setFeeStatus(status);
            return contractCompareConsumptionVO;
        }
        if (Objects.equals(status, ContractCompareFeeStatusEnum.TRIAL.getType())){
            Integer totalCount = contractCompareUtil.getTotalCount(corpid);
            contractCompareConsumptionVO.setFeeStatus(status);
            contractCompareConsumptionVO.setTotalUsedToTotalConsumption(totalCount + "/" + "50");
            return contractCompareConsumptionVO;
        }
        // 日用量
        Integer dayUsed = contractCompareUtil.getDayOrMonthConsumption(corpid, TimeTypeEnum.DAY);
        // 月用量
        Integer monthUsed = contractCompareUtil.getDayOrMonthConsumption(corpid, TimeTypeEnum.MONTH);
        // 截至时间 && 总套餐用量
        List<Integer> feeTypeIn = Collections.singletonList(ValueAddedTypeEnum.CONTRACT_COMPARE.getType());
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("feeTypeIn",feeTypeIn);
        param.put(StringConstant.DEL, DelEnum.NORMAL);
        List<FeeLogEntity> feeLogEntitys = feeLogModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(feeLogEntitys)){
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620005);
        }
        Long deadline = feeLogEntitys.get(0).getEndTime();
        Integer totalConsumption = 0;
        for (FeeLogEntity feeLogEntity : feeLogEntitys) {
            Long endTime = feeLogEntity.getEndTime();
            if (deadline < endTime){
                deadline = endTime;
            }
            totalConsumption = totalConsumption + feeLogEntity.getSumValue();
        }

        Integer totalUsed = 0;
        AtomicInteger atomicTotalUsed = new AtomicInteger(monthUsed);
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias("contractCompareUseed", corpid);
        // 首次统计
        if (Objects.isNull(companyConfigEntity)){
            companyConfigEntity = new CompanyConfigEntity(corpid, "合同比对用量", "contractCompareUseed", "0");
            companyConfigModel.insert(companyConfigEntity);
        }
        long time = DateTimeUtil.getFirstDateOfThisMonth();
        Long updateTime = companyConfigEntity.getUpdateTime();
        /**
         *  判断本月有没有更新过
         * 思路：每个月第一次进来时更新总用量（总用量= 总用量+上个月的总用量）
         */
        if (updateTime < time){
            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put("compareStatus",ContractCompareStatusEnum.SUCCESS.getCode());
            param.put("startUseTime", DateTimeUtil.getFirstDateOfLastMonth());
            param.put("endUseTime", DateTimeUtil.getLastDateOfLastMonth(DateTimeUtil.getInt()));
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            // 上个月的总用量
            Integer count = contractCompareModel.getEntityCount(param);
            String value = companyConfigEntity.getConfigValue();
            Integer total = Integer.parseInt(value);
            // 更新总用量：开始使用 ---> 上个月最后一次使用
            AtomicInteger atomicTotal = new AtomicInteger(total);
            atomicTotal.addAndGet(count);
            total = atomicTotal.get();
            companyConfigEntity.setConfigValue(total.toString());
            companyConfigModel.update(companyConfigEntity);
        }
        Integer total = Integer.parseInt(companyConfigEntity.getConfigValue());
        atomicTotalUsed.addAndGet(total);
        totalUsed = atomicTotalUsed.get();
        contractCompareConsumptionVO.setDayUsed(dayUsed.toString());
        contractCompareConsumptionVO.setMonthUsed(monthUsed.toString());
        contractCompareConsumptionVO.setDeadLine(deadline.toString());
        contractCompareConsumptionVO.setTotalUsedToTotalConsumption(totalUsed + "/" + totalConsumption);
        contractCompareConsumptionVO.setFeeStatus(status);
        return contractCompareConsumptionVO;
    }

    @Override
    public ContractCompareOrderVO getOrderInfo(ContractCompareOrderDTO contractCompareOrderDTO) throws XbbException {
        ContractCompareOrderVO contractCompareOrderVO = new ContractCompareOrderVO();
        String corpid = contractCompareOrderDTO.getCorpid();
        Integer page = contractCompareOrderDTO.getPage();
        Integer pageSize = contractCompareOrderDTO.getPageSize();

        List<Integer> feeTypeIn = Collections.singletonList(ValueAddedTypeEnum.CONTRACT_COMPARE.getType());
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("feeTypeIn",feeTypeIn);
        param.put("page",page);
        param.put("orderByStr","start_time");
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        PageHelper pageHelper = PageHelperUtil.getPageHelper(param, feeLogModel, pageSize);
        List<FeeLogEntity> feeLogEntitys = (List<FeeLogEntity>)PageHelperUtil.getEntityList(param, pageHelper, feeLogModel);
        if (CollectionsUtil.isEmpty(feeLogEntitys)){
            throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620005);
        }
        // 统计总用量
        param.clear();
        param.put(StringConstant.CORPID, corpid);
        param.put("compareStatus",0);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Integer count = contractCompareModel.getEntityCount(param);
        boolean leftUseUp = true;
        if (page > 1){
            int sumRow = (page-1) * pageSize;
            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put("feeTypeIn",feeTypeIn);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("start",0);
            param.put("pageNum",sumRow);
            param.put("orderByStr","start_time");
            List<FeeLogEntity> feeLogList = feeLogModel.findEntitys(param);
            int leftFeeSum = feeLogList.stream().mapToInt(FeeLogEntity::getSumValue).sum();
            // 左侧已用光
            if (leftFeeSum > count){
                leftUseUp = false;
            } else {
                count = count -leftFeeSum;
            }
        }
        List<ContractCompareFeeInfoPojo> feeInfoList = new ArrayList<>();
        for (FeeLogEntity feeLogEntity : feeLogEntitys) {
            ContractCompareFeeInfoPojo contractCompareFeeInfoPojo = new ContractCompareFeeInfoPojo();
            Integer sumValue = feeLogEntity.getSumValue();
            contractCompareFeeInfoPojo.setFeeSum(sumValue.toString());
            contractCompareFeeInfoPojo.setBuyTime(feeLogEntity.getStartTime().toString());
            contractCompareFeeInfoPojo.setDeadLine(feeLogEntity.getEndTime().toString());
            contractCompareFeeInfoPojo.setFeeName(feeLogEntity.getFeeName());
            if (!leftUseUp){
                contractCompareFeeInfoPojo.setUsedNum("0");
                contractCompareFeeInfoPojo.setSurplusNum(sumValue.toString());
                feeInfoList.add(contractCompareFeeInfoPojo);
                continue;
            }
            if (sumValue > count){
                contractCompareFeeInfoPojo.setUsedNum(count + "");
                contractCompareFeeInfoPojo.setSurplusNum(sumValue - count + "");
                count = 0;
            }else {
                contractCompareFeeInfoPojo.setUsedNum(sumValue.toString());
                contractCompareFeeInfoPojo.setSurplusNum("0");
                count = count - sumValue;
            }
            feeInfoList.add(contractCompareFeeInfoPojo);
        }
        contractCompareOrderVO.setFeeInfoList(feeInfoList);
        contractCompareOrderVO.setPageHelper(pageHelper);
        return contractCompareOrderVO;
    }

    @Override
    public ContractCompareMsgVO getMoreCompareNum(ContractCompareGetMoreSumDTO contractCompareGetMoreSumDTO) throws XbbException {
        ContractCompareMsgVO contractCompareMsgVO = new ContractCompareMsgVO();
        String corpid = contractCompareGetMoreSumDTO.getCorpid();
        CompanyEntity companyEntity = companyModel.getByKey(corpid);
        AppModuleSaveDTO saveDTO = new AppModuleSaveDTO();
        BeanUtil.copyProperties(contractCompareGetMoreSumDTO, saveDTO);
        saveDTO.setCompanyName(companyEntity.getCorpName());
//        saveDTO.setAlias(ValueAddedTypeEnum.CONTRACT_COMPARE_INC_PACKAGE.getAlias());
        appModuleService.addSalesOpportunity(saveDTO);
        return contractCompareMsgVO;
    }

    @Override
    public ContractDataListVO getContractDataList(ContractDataListDTO contractDataListDTO) throws XbbException {
        ContractDataListVO contractDataListVO = new ContractDataListVO();

        String corpid = contractDataListDTO.getCorpid();
//        List<ConditionsEntityExt> conditions = new ArrayList<>();
//        // 统一设置审批状态，默认只获取0（无需审批）,2（审批通过）状态的数据
//        conditions.add(new ConditionsEntityExt(FieldTypeEnum.FLOW_STATUS.getAlias(), "", FieldTypeEnum.FLOW_STATUS.getType(), ConditionEnum.IN.getSymbol(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
//        // 只能搜到没有删除的数据
//        contractDataListDTO.setDel(0);
//        contractDataListDTO.setSimple(false);
////        EsConditionUtil.isRed(conditions, 0);
//        contractDataListDTO.setConditions(conditions);
        List<String> fieldList = contractDataListDTO.getFieldList();
        Integer businessType = contractDataListDTO.getBusinessType();
        fieldList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        fieldList.addAll(BusinessFieldEnum.getByBusinessType(businessType));
        contractDataListDTO.setFieldList(fieldList);

        try {
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, 1);

            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            //解析查询条件
            EsUtil.parseCondition(boolQueryBuilder, contractDataListDTO.getConditions(), "", corpid, businessType);

            boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT+ StringConstant.KEY_WORD, corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.FORM_ID, contractDataListDTO.getFormId()));
            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, 0));
            sourceBuilder.query(boolQueryBuilder);

            sourceBuilder.sort(new FieldSortBuilder("updateTime").order(SortOrder.DESC));
            sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));

            businessType = XbbRefTypeEnum.transferBusinessType2Index(businessType);

            //模糊查询
            String nameLike = contractDataListDTO.getNameLike();
            if (StringUtil.isNotEmpty(nameLike)){
                List<String> searchAttrList;
                searchAttrList = ListSearchEnum.getByBusinessType(businessType, false);
                BoolQueryBuilder innerBoolQueryBuilder = boolQuery();
                if (CollectionsUtil.isNotEmpty(searchAttrList)) {
                    innerBoolQueryBuilder.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
                    for (String attr : searchAttrList) {
                        innerBoolQueryBuilder.should(matchPhraseQuery(attr, nameLike));
                        innerBoolQueryBuilder.should(matchPhraseQuery(attr + StringConstant.POINT + StringConstant.KEY_WORD, nameLike));
                    }
                }
                boolQueryBuilder.filter(innerBoolQueryBuilder);
            }
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
            PageRequest pageRequest= EsUtil.setPage(sourceBuilder, contractDataListDTO.getPage(), contractDataListDTO.getPageSize());
            SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
            searchRequest.source(sourceBuilder);
            //分页
            XbbAggregatedPage<PaasFormDataEntityExt> xbbAggregatedPage = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
            List<PaasFormDataEntityExt> resultList = xbbAggregatedPage.getContent();
            long num =  xbbAggregatedPage.getTotalElements();
            PageHelper pageHelper = new PageHelper(contractDataListDTO.getPage(), contractDataListDTO.getPageSize());
            pageHelper.setRowsCount((int) num);
            contractDataListVO.setPaasFormDataESList(resultList);
            contractDataListVO.setPageHelper(pageHelper);
            contractDataListVO.setBusinessType(contractDataListDTO.getBusinessType());
            // headList处理
            PaasFormEntityExt formEntityExt = new PaasFormEntityExt();
            BeanUtil.copyProperties(contractDataListDTO, formEntityExt);
            formEntityExt.setId(contractDataListDTO.getFormId());
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(contractDataListDTO.getFormId(), corpid);
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            explainList = explainHelp.handleExplain(explainList, fieldList, formEntityExt);
            contractDataListVO.setHeadList(explainList);
            contractDataListVO.setForm(formEntityExt);
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains());
            // 可见权限判断
            for (String attr : fieldList) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                for (PaasFormDataEntityExt paasFormDataEntityExt : resultList) {
                    Long dataId = paasFormDataEntityExt.getDataId();
                    List<Long> dataIdIn = new ArrayList<>();
                    dataIdIn.add(dataId);
                    //协同团队
                    Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    if (CollectionsUtil.isNotEmpty(dataIdIn)){
                        userTeamHelp.setUserIdMap(dataIdIn, corpid, businessType, false, mainUserMap, coUserMap);
                    }
                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();

                    handlerExplainDTO.setOwnerId(mainUserMap.get(dataId));
                    handlerExplainDTO.setCoUserId(coUserMap.get(dataId));
                    handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
                    handlerExplainDTO.setLoginUser(contractDataListDTO.getLoginUser());
                    handlerExplainDTO.setUserId(contractDataListDTO.getUserId());
                    boolean canSee = commonHelp.attrCanSee(attr, explainMap, handlerExplainDTO);
                    JSONObject data = paasFormDataEntityExt.getData();
                    if (!canSee){
                        data.put(attr, null);
                    }
                }
            }
        } catch (XbbException e) {
            LOG.error("---------------get contractDataList fail",e);
        }
        return contractDataListVO;
    }


    @Override
    public JSONObject getContractCompareResultUrl(ContractCompareUrlDTO contractCompareUrlDTO) throws XbbException {
        JSONObject result = new JSONObject(BasicConstant.ONE);
        String secret = URLEncodeUtils.decodeURL(contractCompareUrlDTO.getSecret());
        String decodeSecret = contractCompareUtil.getDecodeSecret(secret);
        if (StringUtil.isNotEmpty(decodeSecret)) {
            ContractCompareUrlPojo contractCompareUrlPojo = JSON.parseObject(decodeSecret, ContractCompareUrlPojo.class);
            Integer urlOpenSource = contractCompareUrlPojo.getUrlOpenSource();

            long contractCompareId = contractCompareUrlPojo.getContractCompareId();
            ContractCompareEntity compareEntity = contractCompareModel.getByKey(contractCompareId, contractCompareUrlDTO.getCorpid());
            if (Objects.nonNull(compareEntity)) {
                if (!contractCompareUtil.getShowCrmUrlPermission(contractCompareUrlDTO.getCorpid(), contractCompareId, contractCompareUrlDTO.getLoginUser(), urlOpenSource)) {
                    // 没有查看权限时，前端开发者说不可报错，故此处封装错误信息后返回
                    result.put("msg", I18nMessageUtil.getMessage(ContractCompareErrorCodeEnum.API_ERROR_1620012.getMsg()));
                    result.put("code", ContractCompareErrorCodeEnum.API_ERROR_1620012.getCode());
                    return result;
                }

                String resultUrl = compareEntity.getResultUrl();
                if (StringUtil.isNotEmpty(resultUrl)) {
                    // compareEntity.getResultUrl() 存储的可能是三方返回的message信息（ContractCompareServiceImpl.startCompare）
                    if (RegexUtil.isUrl(resultUrl)) {
                        result.put("code", BasicConstant.ONE);
                        result.put("resultUrl", resultUrl);
                    } else {
                        throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620011, compareEntity.getResultUrl());
                    }
                }
            } else {
                throw new XbbException(ContractCompareErrorCodeEnum.API_ERROR_1620011);
            }
        }
        return result;
    }
}
